package com.zpz.framework.zpzoauth.config.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.zpz.framework.zpzoauth.common.result.CommonResult;
import com.zpz.framework.zpzoauth.common.result.ZpzOauthResultStatus;
import com.zpz.framework.zpzoauth.common.utils.ZpzOauthCommonConstant;
import com.zpz.framework.zpzoauth.common.utils.ZpzOauthRequestUtil;
import com.zpz.framework.zpzoauth.pojo.po.OauthClientDetails;
import com.zpz.framework.zpzoauth.pojo.vo.GetAccessByRoleVo;
import com.zpz.framework.zpzoauth.service.ZpzOauthPermissionService;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * @author zhangpanzhi
 * @description
 * @create 2020-03-21 23:33
 */
@Component
@ControllerAdvice(basePackages = {"com.zpz.framework.zpzoauth","org.springframework.security.oauth2.provider.endpoint"})
//@Slf4j
public class EncryResponseBodyAdvice implements ResponseBodyAdvice<Object> {
    private Logger log = LoggerFactory.getLogger(EncryResponseBodyAdvice.class);

    @Value("${zpzOauth.encrypt.respenable}")
    private Boolean respenable;
    @Resource
    private ZpzOauthPermissionService permissionService;
    @Resource
    private ZpzOauthRequestUtil zpzOauthRequestUtil;
    public static String APPLICATION_NAME;

    @Value("${zpzOauth.redis.pre}")
    public void setApplicationName(String applicationName) {
        APPLICATION_NAME = applicationName;
    }


    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object obj, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {

        // 是否启用加解密安全配置
        if (!respenable){
            return obj;
        }
        Map<String,Object> _body =null;
        String type = selectedContentType.getType();
        String subtype = selectedContentType.getSubtype();
        ServletServerHttpRequest sshr = (ServletServerHttpRequest) serverHttpRequest;
        HttpServletRequest request = sshr.getServletRequest();
        if ((type+"/"+subtype).equals("application/json")&&!request.getRequestURI().equals("/api/error/exthrow")){
        //此处获取到request 是为了取到在拦截器里面设置的一个对象 是我项目需要,可以忽略
            String lience = request.getHeader(ZpzOauthCommonConstant.REQUEST_HEADER_LIENCE);
            String clientId = null;
            String apicode = null;
            if (StringUtils.isNotBlank(lience)) {
                String _license = new String(Base64.decodeBase64(lience));
                String[] liencese = _license.split(":");
                apicode = liencese[1];
                clientId=liencese[0];
            }
            OauthClientDetails client=zpzOauthRequestUtil.getClient(clientId);
            if (client == null){
                _body = CommonResult.getResponseBody(apicode, ZpzOauthResultStatus.EXCEPTION, null,"无效的客户端", ZpzOauthCommonConstant.SET_EN_NOT_VALUE, ZpzOauthCommonConstant.SET_CHECK_SIGN_NOT_VALUE,client);
                return _body;
            }
            List<GetAccessByRoleVo> accessByRoleVos = null;
            try {
                accessByRoleVos = permissionService.getAccessByClient();
            } catch (Exception e) {
                e.printStackTrace();
                _body = CommonResult.getResponseBody(apicode, ZpzOauthResultStatus.GATE_WAY_10031, null,"业务响应数据为空", ZpzOauthCommonConstant.SET_EN_NOT_VALUE, ZpzOauthCommonConstant.SET_CHECK_SIGN_NOT_VALUE,client);
                return _body;
            }
            //                匹配路径 判断是否需要加解密签名
            if (accessByRoleVos == null) {
                _body = CommonResult.getResponseBody(apicode, ZpzOauthResultStatus.GATE_WAY_10031, null,"业务响应数据为空", ZpzOauthCommonConstant.SET_EN_NOT_VALUE, ZpzOauthCommonConstant.SET_CHECK_SIGN_NOT_VALUE,client);
                return _body;
            }
            String set_en = null;
            String set_sign = null;
            String requestURI = request.getRequestURI();
            for (GetAccessByRoleVo v : accessByRoleVos) {
                if (v.getMethodUrl().equals(requestURI)) {
                    set_en = v.getSetEn() + "";
                    set_sign = v.getSetSign() + "";
                }
            }
            String s = JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect);
            _body = CommonResult.getResponseBody(apicode,ZpzOauthResultStatus.OK,s,null, set_en, set_sign,client);
            return _body;
        }
        return obj;
    }

}
